"""CronJob资源提取器模块"""

from typing import Dict, Any, Optional, List
import yaml
import logging
from src.extractors.base import Extractor

class CronJobExtractor(Extractor):
    """
    CronJob资源提取器
    负责从CronJob资源定义中提取关键信息
    """
    
    def __init__(self, logger: Optional[logging.Logger] = None):
        """初始化CronJob提取器"""
        super().__init__(logger)
        self.resource_type = "CronJob"
    
    def extract(self, content: str, file_path: str = "") -> Dict[str, Any]:
        """
        从CronJob YAML/JSON内容中提取信息
        
        Args:
            content: YAML/JSON格式的资源内容
            file_path: 资源文件路径，可选，用于日志记录
            
        Returns:
            提取的CronJob资源信息字典
        """
        # 解析YAML/JSON内容
        resource = self.parse_content(content, file_path)
        if not resource:
            return {}
            
        # 检查是否为CronJob资源
        if resource.get("kind") != "CronJob":
            self.logger.warning(f"资源不是CronJob: {file_path}")
            return {}
            
        # 提取基本信息
        result = self._extract_basic_info(resource)
        
        # 提取调度信息
        self._extract_schedule_info(resource, result)
        
        # 提取作业配置
        self._extract_job_config(resource, result)
        
        # 提取任务模板
        self._extract_job_template(resource, result)
        
        # 提取状态信息
        self._extract_status(resource, result)
        
        return result
    
    def _extract_basic_info(self, resource: Dict[str, Any]) -> Dict[str, Any]:
        """
        提取基本元数据信息
        
        Args:
            resource: 解析后的资源字典
            
        Returns:
            包含基本信息的字典
        """
        metadata = resource.get("metadata", {})
        
        result = {
            "kind": "CronJob",
            "name": metadata.get("name", ""),
            "namespace": metadata.get("namespace", "default"),
            "creation_timestamp": metadata.get("creationTimestamp", "")
        }
        
        # 提取标签和注解
        if "labels" in metadata:
            result["labels"] = metadata.get("labels", {})
            
        if "annotations" in metadata:
            result["annotations"] = metadata.get("annotations", {})
            
        return result
    
    def _extract_schedule_info(self, resource: Dict[str, Any], result: Dict[str, Any]) -> None:
        """
        提取CronJob调度信息
        
        Args:
            resource: 解析后的资源字典
            result: 要填充的结果字典
        """
        spec = resource.get("spec", {})
        
        # 提取cron表达式
        if "schedule" in spec:
            result["schedule"] = spec.get("schedule", "")
        
        # 提取时区
        if "timeZone" in spec:
            result["timezone"] = spec.get("timeZone", "")
        
        # 提取启动截止时间
        if "startingDeadlineSeconds" in spec:
            result["starting_deadline_seconds"] = spec.get("startingDeadlineSeconds", 0)
    
    def _extract_job_config(self, resource: Dict[str, Any], result: Dict[str, Any]) -> None:
        """
        提取CronJob配置信息
        
        Args:
            resource: 解析后的资源字典
            result: 要填充的结果字典
        """
        spec = resource.get("spec", {})
        
        # 并发策略
        if "concurrencyPolicy" in spec:
            result["concurrency_policy"] = spec.get("concurrencyPolicy", "")
        
        # 历史保留限制
        if "successfulJobsHistoryLimit" in spec:
            result["successful_jobs_history_limit"] = spec.get("successfulJobsHistoryLimit", 3)
        
        if "failedJobsHistoryLimit" in spec:
            result["failed_jobs_history_limit"] = spec.get("failedJobsHistoryLimit", 1)
        
        # 暂停
        if "suspend" in spec:
            result["suspend"] = spec.get("suspend", False)
    
    def _extract_job_template(self, resource: Dict[str, Any], result: Dict[str, Any]) -> None:
        """
        提取Job模板信息
        
        Args:
            resource: 解析后的资源字典
            result: 要填充的结果字典
        """
        spec = resource.get("spec", {})
        job_template = spec.get("jobTemplate", {})
        
        if not job_template:
            return
        
        # 提取Job模板
        result["job_template"] = {}
        
        # 提取Job规格
        job_spec = job_template.get("spec", {})
        if job_spec:
            result["job_template"]["spec"] = {}
            
            # 提取完成期限
            if "activeDeadlineSeconds" in job_spec:
                result["job_template"]["spec"]["active_deadline_seconds"] = job_spec.get("activeDeadlineSeconds", 0)
            
            # 提取重试限制
            if "backoffLimit" in job_spec:
                result["job_template"]["spec"]["backoff_limit"] = job_spec.get("backoffLimit", 6)
            
            # 提取并行度
            if "parallelism" in job_spec:
                result["job_template"]["spec"]["parallelism"] = job_spec.get("parallelism", 1)
            
            # 提取完成要求
            if "completions" in job_spec:
                result["job_template"]["spec"]["completions"] = job_spec.get("completions", 1)
            
            # 提取Pod模板
            pod_template = job_spec.get("template", {})
            if pod_template:
                result["job_template"]["spec"]["template"] = {}
                
                # 提取Pod规格
                pod_spec = pod_template.get("spec", {})
                if pod_spec:
                    result["job_template"]["spec"]["template"]["spec"] = {}
                    
                    # 提取重启策略
                    if "restartPolicy" in pod_spec:
                        result["job_template"]["spec"]["template"]["spec"]["restart_policy"] = pod_spec.get("restartPolicy", "")
                    
                    # 提取容器信息
                    containers = pod_spec.get("containers", [])
                    if containers:
                        result["containers"] = self._extract_containers(containers)
                    
                    # 提取卷信息
                    volumes = pod_spec.get("volumes", [])
                    if volumes:
                        result["volumes"] = self._extract_volumes(volumes)
    
    def _extract_containers(self, containers: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        提取容器信息
        
        Args:
            containers: 容器列表
            
        Returns:
            处理后的容器信息列表
        """
        result = []
        
        for container in containers:
            container_info = {
                "name": container.get("name", ""),
                "image": container.get("image", "")
            }
            
            # 提取镜像拉取策略
            if "imagePullPolicy" in container:
                container_info["image_pull_policy"] = container.get("imagePullPolicy", "")
            
            # 提取命令和参数
            if "command" in container:
                container_info["command"] = container.get("command", [])
            
            if "args" in container:
                container_info["args"] = container.get("args", [])
            
            # 提取环境变量
            if "env" in container:
                container_info["env"] = self._extract_env_vars(container.get("env", []))
            
            # 提取资源限制
            if "resources" in container:
                container_info["resources"] = self._clean_keys(container.get("resources", {}))
            
            # 提取卷挂载
            if "volumeMounts" in container:
                container_info["volume_mounts"] = self._extract_volume_mounts(container.get("volumeMounts", []))
                
            # 提取端口
            if "ports" in container:
                container_info["ports"] = self._extract_container_ports(container.get("ports", []))
            
            # 提取探针
            if "livenessProbe" in container:
                container_info["liveness_probe"] = self._clean_keys(container.get("livenessProbe", {}))
                
            if "readinessProbe" in container:
                container_info["readiness_probe"] = self._clean_keys(container.get("readinessProbe", {}))
                
            if "startupProbe" in container:
                container_info["startup_probe"] = self._clean_keys(container.get("startupProbe", {}))
            
            result.append(container_info)
            
        return result
    
    def _extract_env_vars(self, env_vars: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        提取环境变量
        
        Args:
            env_vars: 环境变量列表
            
        Returns:
            处理后的环境变量列表
        """
        result = []
        
        for env in env_vars:
            env_info = {
                "name": env.get("name", "")
            }
            
            if "value" in env:
                env_info["value"] = env.get("value", "")
            
            if "valueFrom" in env:
                env_info["value_from"] = self._clean_keys(env.get("valueFrom", {}))
            
            result.append(env_info)
            
        return result
    
    def _extract_volume_mounts(self, mounts: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        提取卷挂载信息
        
        Args:
            mounts: 卷挂载列表
            
        Returns:
            处理后的卷挂载列表
        """
        result = []
        
        for mount in mounts:
            mount_info = {
                "name": mount.get("name", ""),
                "mount_path": mount.get("mountPath", "")
            }
            
            if "readOnly" in mount:
                mount_info["read_only"] = mount.get("readOnly", False)
            
            if "subPath" in mount:
                mount_info["sub_path"] = mount.get("subPath", "")
                
            result.append(mount_info)
            
        return result
    
    def _extract_container_ports(self, ports: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        提取容器端口信息
        
        Args:
            ports: 端口列表
            
        Returns:
            处理后的端口列表
        """
        result = []
        
        for port in ports:
            port_info = {
                "container_port": port.get("containerPort", 0)
            }
            
            if "name" in port:
                port_info["name"] = port.get("name", "")
                
            if "protocol" in port:
                port_info["protocol"] = port.get("protocol", "TCP")
                
            result.append(port_info)
            
        return result
    
    def _extract_volumes(self, volumes: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        提取卷信息
        
        Args:
            volumes: 卷列表
            
        Returns:
            处理后的卷列表
        """
        result = []
        
        for volume in volumes:
            volume_info = {
                "name": volume.get("name", "")
            }
            
            # 复制所有卷字段但使用snake_case
            for key, value in volume.items():
                if key != "name":
                    snake_key = self._to_snake_case(key)
                    volume_info[snake_key] = value
                    
            result.append(volume_info)
            
        return result
    
    def _extract_status(self, resource: Dict[str, Any], result: Dict[str, Any]) -> None:
        """
        提取CronJob状态信息
        
        Args:
            resource: 解析后的资源字典
            result: 要填充的结果字典
        """
        status = resource.get("status", {})
        
        if not status:
            return
            
        result["status"] = {}
        
        # 上次调度时间
        if "lastScheduleTime" in status:
            result["status"]["last_schedule_time"] = status.get("lastScheduleTime", "")
        
        # 活跃作业
        if "active" in status:
            result["status"]["active"] = status.get("active", [])
        
        # 上次成功运行时间
        if "lastSuccessfulTime" in status:
            result["status"]["last_successful_time"] = status.get("lastSuccessfulTime", "")
    
    def _to_snake_case(self, camel_case: str) -> str:
        """
        将驼峰命名转换为蛇形命名
        
        Args:
            camel_case: 驼峰命名的字符串
            
        Returns:
            蛇形命名的字符串
        """
        snake_case = ""
        for i, char in enumerate(camel_case):
            if char.isupper():
                if i > 0:
                    snake_case += "_"
                snake_case += char.lower()
            else:
                snake_case += char
        return snake_case
    
    def _clean_keys(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """
        递归清理字典键为蛇形命名
        
        Args:
            data: 要清理的字典
            
        Returns:
            清理后的字典
        """
        result = {}
        
        if not isinstance(data, dict):
            return data
            
        for key, value in data.items():
            new_key = self._to_snake_case(key)
            
            if isinstance(value, dict):
                result[new_key] = self._clean_keys(value)
            elif isinstance(value, list):
                result[new_key] = [
                    self._clean_keys(item) if isinstance(item, dict) else item
                    for item in value
                ]
            else:
                result[new_key] = value
                
        return result